package com.zhengxyou.androiddemo.appBasics.appResources;

import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.AnticipateInterpolator;
import android.view.animation.AnticipateOvershootInterpolator;
import android.view.animation.BounceInterpolator;
import android.view.animation.CycleInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.OvershootInterpolator;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.vectordrawable.graphics.drawable.AnimatorInflaterCompat;

import com.zhengxyou.androiddemo.R;
import com.zhengxyou.androiddemo.appBasics.appResources.animation.InterpolatorActivity;
import com.zhengxyou.androiddemo.appBasics.appResources.colorState.ColorStateActivity;
import com.zhengxyou.androiddemo.appBasics.appResources.drawable.DrawableActivity;

import java.util.Date;
import java.util.Locale;

/**
 * <h3>
 * 应用资源
 * </h3>
 * <pre>
 * <ol>
 * <li>动画</li>
 * <li>颜色状态列表</li>
 * <li>drawable</li>
 * <li>布局</li>
 * <li>菜单</li>
 * <li>字符串</li>
 * <li>样式</li>
 * <li>字体</li>
 * <li>bool</li>
 * <li>color</li>
 * <li>dimension</li>
 * <li>ID</li>
 * <li>Integer</li>
 * <li>Integer Array</li>
 * <li>Typed Array</li>
 * </ol>
 * </pre>
 * <p>
 * 动画：分为属性动画和视图动画</p>
 * <br>
 * <div>
 * <h4>属性动画</h4>
 * <ol>
 * <li>值动画 ValueAnimator--对应标签 <code>animator</code></li>
 * <li>对象动画 ObjectAnimator--对应标签 <code>ObjectAnimator</code></li>
 * <li>动画师集合 AnimatorSet--对应标签 <code>set</code></li>
 * </ol>
 * <br>
 * 动画Xml文件的基本标签释义：<br>
 * <p> <code><set></code> 代表 <code>AnimatorSet</code>,可以包含 <code>ValueAnimator</code>，<code>ObjectAnimator</code>和 <code>set</code>标签
 * 有一个 <code>ordering</code>属性来设定动画集的播放顺序：<br>
 * 有2个值:
 * 1、默认值<code>together</code>同时，一起播放。<br>
 * 2、按顺序播放 <code>sequentially</code>
 * </p>
 * <ol>
 * <li>propertyName:属性名字，如透明度 "alpha","backgroundColor"</li>
 * <li>duration：持续时间，只能填 <code>int</code>整数，时间单位为毫秒</li>
 * <li>repeatCount：循环次数， 只能填  <code>int</code>整数，默认为0，表示不循环，<code>-1</code>的时候为无限循环</li>
 * <li>repeatMode：动画到达结尾的时的行为模式，只有 <code>repeatCount</code>为-1或者为正整数时才有效。有2个值 <code>reverse</code>使动画在每次迭代时反向， <code>restart</code>使动画循环从头始 </li>
 * <li>valueTo: 到哪里为止，可填 <code>float</code>，<code>int</code>或者<code>color颜色值如#333333</code></li>
 * <li>valueFrom：从哪里开始，如ValueTo</li>
 * <li>ValueType：指定动画值类型，当属性值为color的时候不需要设置。有2个值： 默认值为 <code>floatType</code>,<code>intType</code></li>
 * <li>startOffset：开始的偏移量,int,调用 <code>start()</code>方法后动画延迟的毫秒数</li>
 * </ol>
 *
 * <br>
 * <p>
 * 使用方法
 * </p>
 * 第一步：解析xml动画文件，转换为AnimatorSet 动画制作者集合<br>
 * 第2步：通过 <code>setTarget()</code>设置要执行动画的目标对象<br>
 * 第三步：调用 <code>start()</code>方法开始动画
 * </div>
 *
 * <div>
 * <h4>视图动画 ViewAnimation</h4>
 * <p>视图动画分补间动画Tween animation和帧动画Frame animation</p>
 * <p>
 * 有4个补间动画：
 * <ol>
 * <li>alpha 透明度--对应 {@link AlphaAnimation}</li>
 * <li>scale 缩放动画</li>
 * <li>translate 位移动画</li>
 * <li>rotate 旋转动画</li>
 * </ol>
 * Xml文件标签:<br>
 * <p>
 * 跟标签 <code>set</code>,代表AnimatorSet动画集合，可放多个动画，有2个属性值，插值器 <code>android:interpolator</code>,
 * 和 <code>android:shareInterpolator</code>，为 <code>true</code>则所有子元素共享这个动画插值器。
 * </p>
 * <p>
 * <code>set</code>可以包含<code>alpha</code> 透明度动画, <code>scale</code> 缩放动画, <code>translate</code> 位移动画, <code>rotate</code> 旋转动画, 或者 <code>set</code>
 * <br>
 * 视图动画,set的特有属性:
 * <ol>
 * <li>fillBefore,动画结束后是否停留在第一帧,默认为true</li>
 * <li>fillAfter,动画结束后是否停留在最后一帧，默认为false，不能与fillBefore一起用</li>
 * <li>fillEnable,与 android:fillBefore 效果相同，都是在动画结束时，将控件还原到初始化状态</li>
 * <li>zAdjustment,允许在动画播放期间，调整播放内容在Z轴方向的顺序</li>
 * </ol>
 * <b> <code>zAdjustment</code></b>
 * 参数为整型的常量
 * <p>
 * ①normal（0）：正在播放的动画内容保持当前的Z轴顺序，<br>
 * ②top（1）：在动画播放期间，强制把当前播放的内容放到其他内容的上面；<br>
 * ③bottom（-1）：在动画播放期间，强制把当前播放的内容放到其他内容之下<br>
 * 在java的代码：<br>
 * animation.setZAdjustment(Animation.ZORDER_BOTTOM);<br>
 * 在XML中的代码<br> *
 * android:zAdjustment="bottom"
 * </p>
 * <p>
 * <code>alpha</code>有2个特有属性：
 * <ol>
 * <li>fromAlpha，开始时的透明度，只能float类型的值，范围为0.0-1.0。0.0为透明，1.0为不透明</li>
 * <li>toAlpha，结束时的透明度,范围同上</li>
 * </ol>
 * </p>
 * <p>
 * <code>scale</code>的特有属性:
 * <ol>
 * <li>fromXScale,x轴方向开始时的缩放度，float ,1.0时为不缩放</li>
 * <li>toXScale,x轴方向结束时的缩放度，同上</li>
 * <li>fromYScale,y轴方向开始时的缩放度，同上</li>
 * <li>toYScale,y轴方向结束时的缩放度，同上</li>
 * <li>pivotX,x轴缩放时的中心点位置 ，同上，可以设置百分比,如50%,100%</li>
 * <li>pivotY,y轴缩放时中心点的位置，同上</li>
 * </ol>
 * </p>
 * <p>
 * <code>translate</code>属性:<br>
 * <p>有三种格式的值:
 * 1、-100到100以'%'为结尾的值(-100%-100%),表示相对于自身的百分比<br>
 * 2、以'%p'为结尾的值(-100%p-100%p)，表示相对于父级的百分比<br>
 * 3、没有%或者%p后缀的浮点值，表示绝对值
 * </p>
 * 大于0往x轴正方向，y轴正方向偏移，小于0反之
 * <ol>
 * <li>fromXDelta,x轴方向开始时的偏移量,float或者百分比,例子：相对于正常位置的像素偏移5像素(android:fromXDelta=5),相对于自身的百分比 5%，相对于父宽度的百分比 5%p</li>
 * <li>toXDelta,x轴结束时的偏移量，同上</li>
 * <li>fromYDelta,y轴方向开始时的偏移量，同上</li>
 * <li>toYDelta，y轴结束时的偏移量，同上</li>
 * </ol>
 * </p>
 * <p>
 * <code>rotate</code>属性：
 * <ol>
 * <li>fromDegrees,开始时的度数，float</li>
 * <li>toDegrees,结束时的度数,float</li>
 * <li>pivotX, x轴旋转的中心位置,float或者百分比,例子：相对于正常位置的像素偏移5像素(android:fromXDelta=5),相对于自身的百分比 5%，相对于父宽度的百分比 5%p</li>
 * <li>pivotY，y轴旋转的中心位置，同上</li>
 * </ol>
 * </p>
 * </div>
 *
 * <h4>interpolator 插值器</h4>
 * 参考： <a href="https://blog.csdn.net/Afanbaby/article/details/73608874">Android Interpolator(插值器)的介绍和使用</a>
 * <div>
 * 目前有9种插值器<br>
 * <ol>
 * <li> <b>默认值</b>在动画开始与结束的地方速率改变比较慢，在中间的时候加速{@link AccelerateDecelerateInterpolator},资源ID <code>@android:anim/accelerate_decelerate_interpolator</code> </li>
 * <li> 在动画开始的地方速率改变比较慢，然后开始加速 {@link AccelerateInterpolator},@android:anim/accelerate_interpolator</li>
 * <li>开始的时候向后甩一点然后向前,{@link AnticipateInterpolator},@android:anim/anticipate_interpolator</li>
 * <li>开始的时候向后甩一点然后向前超过设定值一点然后返回,{@link AnticipateOvershootInterpolator},@android:anim/anticipate_overshoot_interpolator</li>
 * <li>动画结束的时候弹起，类似小球落地 ,{@link BounceInterpolator},@android:anim/bounce_interpolator</li>
 * <li>动画循环播放特定的次数回到原点，速率改变沿着正弦曲线 ,{@link CycleInterpolator},@android:anim/cycle_interpolator</li>
 * <li>在动画开始的地方快然后慢 ,减速,{@link DecelerateInterpolator},@android:anim/decelerate_interpolator</li>
 * <li>以常量速率改变 ,{@link LinearInterpolator},@android:anim/linear_interpolator</li>
 * <li>向前超过设定值一点然后返回到原来位置,{@link OvershootInterpolator},@android:anim/overshoot_interpolator</li>
 * </ol>
 * </div>
 * <div>
 * <h3>Frame Animation帧动画--AnimationDrawable</h3>
 * 元素:
 * <ul>
 * <ol>根目录 <code>animation-list</code>有一个属性 <code>oneshot</code>,boolean, <code>true</code>为执行一次，<code>false</code> 循环播放</ol>
 * <ol><code>item</code>，有2个属性分别为 <code>drawable</code>图片资源和 <code>duration</code>持续时间</ol>
 * </ul
 * </div>
 *
 * <div>
 * <code>include</code>的 <code>id</code>,<code>width</code>,<code>height</code>会覆盖布局根元素的属性
 * </div>
 *
 * <pre>
 *     主题中的值引用以 ? 开头，而不是以 @ 开头
 * </pre>
 */
public class ResourcesActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_resources);

        changeBackgroundColor();
        changeTextSize();
        changeAll();
        showViewAnimator();
        displayInterpolator();

        displayPlaneLoading();
        displayTypedArray();

        findViewById(R.id.btn_resources_colorStateList).setOnClickListener(v -> ColorStateActivity.start(ResourcesActivity.this));
        findViewById(R.id.btn_resources_drawable).setOnClickListener(v -> DrawableActivity.start(ResourcesActivity.this));
        findViewById(R.id.btn_resources_menu).setOnClickListener(v -> MenuActivity.start(ResourcesActivity.this));
        findViewById(R.id.btn_resources_String).setOnClickListener(v -> StringsActivity.start(ResourcesActivity.this));

        TextView mLocal = findViewById(R.id.tv_resources_local);
        //国际化，获取目前地区
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            Locale locale = getResources().getConfiguration().getLocales().get(0);
            Log.e("TAG", "Local is " + locale.getDisplayName());
            Log.e("TAG", "Local is " + locale.getDisplayCountry() + "," + locale.getDisplayLanguage());

            mLocal.setText(locale.getDisplayName());
        }


        //时间格式
        String skeleton = DateFormat.is24HourFormat(this) ? "Hm" : "hm";
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            String formattedTime = android.icu.text.DateFormat.getInstanceForSkeleton(skeleton, Locale.getDefault()).format(new Date());
            mLocal.append("\n" + formattedTime);
        }
    }

    /**
     * Typed Array
     */
    private void displayTypedArray() {
        TextView typedArray = findViewById(R.id.tv_resources_typed_array);

        TypedArray iconArray = getResources().obtainTypedArray(R.array.icons);
        Drawable drawable = iconArray.getDrawable(0);
        iconArray.recycle();

        TypedArray colorArray = getResources().obtainTypedArray(R.array.colors);
        int color = colorArray.getColor(0, 0);
        colorArray.recycle();


    }

    /**
     * frame animation 帧动画
     */
    private void displayPlaneLoading() {
        ImageView frameImageView = findViewById(R.id.iv_resources_frame_animation);

        frameImageView.setBackgroundResource(R.drawable.resources_frame_animation);
        frameImageView.setOnClickListener(v -> {
            Drawable background = frameImageView.getBackground();
            if (background instanceof Animatable) {
                ((Animatable) background).start();
            }
        });
    }

    /**
     * 插值器演示，还有自定义的
     */
    private void displayInterpolator() {
        findViewById(R.id.btn_resources_interpolate).setOnClickListener(v -> InterpolatorActivity.start(ResourcesActivity.this));
    }

    /**
     * 视图动画测试
     */
    private void showViewAnimator() {
        ImageView mViewAnimator = findViewById(R.id.iv_resources_viewAnimator);

        mViewAnimator.setOnClickListener(v -> {
//            AnimationUtilsCompat
            Animation animation = AnimationUtils.loadAnimation(ResourcesActivity.this, R.anim.hyperspace_jump);
//            animation.setZAdjustment(Animation.ZORDER_TOP);
            animation.setZAdjustment(Animation.ZORDER_BOTTOM);
            mViewAnimator.startAnimation(animation);
        });
    }

    /**
     * 动画集合，多种动画集合
     */
    private void changeAll() {
        TextView mAll = findViewById(R.id.tv_resources_all);
        mAll.setOnClickListener(v -> {
//            AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(ResourcesActivity.this, R.animator.resources_bg_and_siez_change_seq);
            AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(ResourcesActivity.this, R.animator.resources_bg_and_siez_change_together);
            set.setTarget(mAll);
            set.start();
        });
    }

    /**
     * valueAnimator值动画，改变字体大小
     */
    private void changeTextSize() {
        TextView mSize = findViewById(R.id.tv_resources_size);
        mSize.setOnClickListener(v -> {
            ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(ResourcesActivity.this, R.animator.resources_text_size_change);
//            animator.setTarget(mSize);
            animator.addUpdateListener(animation -> {
                float animatedValue = (float) animation.getAnimatedValue();
                mSize.setTextSize(animatedValue);
            });
            animator.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {

                }

                @Override
                public void onAnimationEnd(Animator animation) {

                }

                @Override
                public void onAnimationCancel(Animator animation) {

                }

                @Override
                public void onAnimationRepeat(Animator animation) {

                }
            });
            animator.start();
        });
    }

    /**
     * 对象动画，改变背景色
     */
    private void changeBackgroundColor() {
        TextView mBackground = findViewById(R.id.tv_resources_backGroundChange);
        mBackground.setOnClickListener(v -> {
            Animator animator = AnimatorInflaterCompat.loadAnimator(this, R.animator.resources_color_change);
//        Animator animator = AnimatorInflater.loadAnimator(this, R.animator.resources_color_change);
            animator.setTarget(mBackground);
            animator.start();
        });
    }

    public static void start(Context context) {
        Intent starter = new Intent(context, ResourcesActivity.class);
        context.startActivity(starter);
    }
}
